home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / db / esm-3.1 / esm-3 / usr / local / sm / src / serverlib / trans / logTransDeallocPages.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-05  |  6.3 KB  |  231 lines

  1. /*
  2.  *   $RCSfile: logTransDeallocPages.c,v $  
  3.  *   $Revision: 1.1.1.1 $  
  4.  *   $Date: 1996/05/04 21:56:02 $      
  5.  */ 
  6. /**********************************************************************
  7. * EXODUS Database Toolkit Software
  8. * Copyright (c) 1991 Computer Sciences Department, University of
  9. *                    Wisconsin -- Madison
  10. * All Rights Reserved.
  11. *
  12. * Permission to use, copy, modify and distribute this software and its
  13. * documentation is hereby granted, provided that both the copyright
  14. * notice and this permission notice appear in all copies of the
  15. * software, derivative works or modified versions, and any portions
  16. * thereof, and that both notices appear in supporting documentation.
  17. *
  18. * THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY OF WISCONSIN --
  19. * MADISON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION.  
  20. * THE DEPARTMENT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
  21. * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  22. *
  23. * The EXODUS Project Group requests users of this software to return 
  24. * any improvements or extensions that they make to:
  25. *
  26. *   EXODUS Project Group 
  27. *     c/o David J. DeWitt and Michael J. Carey
  28. *   Computer Sciences Department
  29. *   University of Wisconsin -- Madison
  30. *   Madison, WI 53706
  31. *
  32. *     or exodus@cs.wisc.edu
  33. *
  34. * In addition, the EXODUS Project Group requests that users grant the 
  35. * Computer Sciences Department rights to redistribute these changes.
  36. **********************************************************************/
  37.  
  38. #include "sysdefs.h"
  39. #include "ess.h"
  40. #include "checking.h"
  41. #include "trace.h"
  42. #include "error.h"
  43. #include "list.h"
  44. #include "pool.h"
  45. #include "tid.h"
  46. #include "io.h"
  47. #include "lock.h"
  48. #include "object.h"
  49. #include "msgdefs.h"
  50. #include "thread.h"
  51. #include "semaphore.h"
  52. #include "latch.h"
  53. #include "link.h"
  54. #include "lsn.h"
  55. #include "bf.h"
  56. #include "bf_macro.h"
  57. #include "volume.h"
  58. #include "openlog.h"
  59. #include "trans.h"
  60. #include "page.h"
  61. #include "bitmap.h"
  62. #include "deallocinfo.h"
  63. #include "io_extfuncs.h"
  64. #include "trans_extfuncs.h"
  65. #include "bf_extfuncs.h"
  66. #include "bm_globals.h"
  67.  
  68.  
  69. /*
  70.  *    This function traverses the list of pages to deallocate (attached
  71.  *    to the transRec) and logs the deallocation.  It collects chunks
  72.  *    of pages to log in one record.  These chunks are created by
  73.  *    cl_DeallocPages.  The chunk size will be the minimum of
  74.  *     MAX_PIDLIST_SIZE, pages on one bitmap page, and the chunk size
  75.  *    from the call to cl_DeallocPages.
  76.  */
  77.  
  78.  int
  79. logTransDeallocPages (
  80.  
  81.     TRANSREC        *transRec,
  82.     LIST            *pendingBitmapList   
  83. )
  84. {
  85.  
  86.     PID             pidList[MAX_PIDLIST_SIZE];
  87.     PAGEDEALLOCINFO *currPage;
  88.     PAGE2SIZE        page2size;
  89.     PAGECONTEXT        *currBitmapPage;
  90.     PAGECONTEXT        *pendingBitmapPage;
  91.     VOLREC            *volRec;
  92.     LIST            bitmapList;  
  93.     int                chunk;
  94.     int                totalChunks;
  95.     int                totalPages;
  96.     int                loggedPages;
  97.     int                chunkPages;
  98.  
  99.     TRACE(TR_TRANS, TR_LEVEL_1);
  100.  
  101.     SM_ASSERT(LEVEL_3, LIST_EMPTY(pendingBitmapList));
  102.  
  103.     /*
  104.      *    See if there is any work to be done;
  105.      */
  106.     currPage = (PAGEDEALLOCINFO*) FIRST_LIST_ELEMENT(&(transRec->pageDeallocList));
  107.     if (currPage == NULL) {
  108.         return(esmNOERROR);
  109.     }
  110.  
  111.     /*
  112.      *    Initialize locals
  113.      */
  114.     initializeList(&bitmapList);
  115.  
  116.     /*
  117.      *    Process each chunk of pages
  118.      */
  119.     while (currPage != NULL) {
  120.  
  121.         CHECK_PAGEDEALLOCINFO_MAGIC(currPage);
  122.         page2size = currPage->page2size;
  123.         SM_ASSERT(LEVEL_3, LIST_EMPTY(&bitmapList));
  124.  
  125.         /*
  126.          *    This is the first page in a chunk, so see how many pages
  127.          *    to deallocate.  Deallocate in chunks which are of 
  128.          *    a size <= MAX_PIDLIST_SIZE.
  129.          */
  130.         SM_ASSERT(LEVEL_3, currPage->pageCount > 0);
  131.         totalPages = currPage->pageCount;
  132.         totalChunks = (totalPages / MAX_PIDLIST_SIZE) + 
  133.                       ((totalPages%MAX_PIDLIST_SIZE) ? 1:0); 
  134.         loggedPages = 0; 
  135.         for (chunk = 0; chunk < totalChunks; chunk++) {
  136.  
  137.             chunkPages = 0;
  138.             while (chunkPages < MAX_PIDLIST_SIZE) {
  139.  
  140.                 /*
  141.                  *    Make sure the page is the right size and add it
  142.                  *    to the list 
  143.                  */
  144.                 SM_ASSERT(LEVEL_3, page2size == currPage->page2size);
  145.                 pidList[chunkPages] = currPage->pid;
  146.                 chunkPages++;
  147.  
  148.                 /*
  149.                  *    Get the next page to log
  150.                  */
  151.                 currPage = (PAGEDEALLOCINFO*) NEXT_LIST_ELEMENT(&(currPage->list));
  152.                 if (currPage == NULL) break;
  153.                 if (currPage->pageCount != 0) {
  154.                     /*
  155.                      *    Starting new chunk, so make sure we've logged
  156.                      *    everything for the current chunk
  157.                      */
  158.                     SM_ASSERT(LEVEL_3, (chunkPages + MAX_PIDLIST_SIZE * chunk) == totalPages);
  159.                     SM_ASSERT(LEVEL_3, chunk+1 == totalChunks);
  160.                     break;
  161.                 }
  162.             }    
  163.  
  164.             /*
  165.              *    Log the deallocation, but don't actually perform it 
  166.              */
  167.             if (io_DeallocPages(page2size, chunkPages, pidList, &bitmapList, TRUE, FALSE) != esmNOERROR) {
  168.                 SM_ERROR(TYPE_CRASH, esmINTERNAL);
  169.             }
  170.  
  171.             /*
  172.              *    For each bitmap page, add it to the pending list
  173.              *    if not already there.
  174.              */
  175.             while ((currBitmapPage = (PAGECONTEXT*) listDeq(&bitmapList)) != NULL) {
  176.                 /*
  177.                  *    see if its already on the pending list
  178.                  */
  179.                 pendingBitmapPage = (PAGECONTEXT*) FIRST_LIST_ELEMENT(pendingBitmapList);
  180.                 while (pendingBitmapPage != NULL) {
  181.                     if (PIDEQ(currBitmapPage->pid, pendingBitmapPage->pid)) {
  182.                         /* the page is on the list, so break */
  183.                           break;
  184.                     }
  185.                     pendingBitmapPage = (PAGECONTEXT*) NEXT_LIST_ELEMENT(&(pendingBitmapPage->list));
  186.                 }
  187.  
  188.                 if (pendingBitmapPage == NULL) {
  189.                     /*
  190.                      *    It's not on the pending list, so add it,
  191.                      *    release its semaphore, and mark it pending
  192.                      */
  193.                     listEnq(pendingBitmapList, &(currBitmapPage->list));
  194.                     signalSemaphore( &(currBitmapPage->groupLink->pageHash->semaphore) );
  195.                     currBitmapPage->groupLink->pageHash->pendingOpCount++;
  196.                     currBitmapPage->bitsChanged = 0;
  197.  
  198.                     /*
  199.                      *    Mark its volume header as having pending 
  200.                      *    operations
  201.                      */
  202.                     volRec = io_FindVolRec(currBitmapPage->pid.volid);
  203.                     if (volRec == NULL) {
  204.                         SM_ERROR(TYPE_FATAL, esmINTERNAL);
  205.                     }
  206.                     volRec->headerLink->pageHash->pendingOpCount++;
  207.                     
  208.                 } else {
  209.  
  210.                     /*
  211.                      *    It's on the pending list, release its
  212.                      *    semaphore, unfix it, and return it to the pool.
  213.                      */
  214.                     signalSemaphore( &(currBitmapPage->groupLink->pageHash->semaphore) );
  215.                     bf_UnfixPage(currBitmapPage->groupLink, BF_DEFAULT, TRUE);
  216.                     poolEnq(&PageContextPool, &(currBitmapPage->list));
  217.                     
  218.                 }
  219.             }
  220.  
  221.             loggedPages += chunkPages;
  222.  
  223.         }
  224.  
  225.         SM_ASSERT(LEVEL_3, loggedPages == totalPages);
  226.  
  227.     }
  228.  
  229.     return(esmNOERROR);
  230. }
  231.